package com.itheima.wms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.wms.common.constants.CodeConstant;
import com.itheima.wms.common.enums.*;
import com.itheima.wms.common.service.CrudServiceImpl;
import com.itheima.wms.dao.*;
import com.itheima.wms.entity.*;
import com.itheima.wms.factory.CodeWorker;
import com.itheima.wms.service.GroundingService;
import com.itheima.wms.service.IncreaseDecreaseService;
import com.itheima.wms.service.StatusRecordService;
import com.itheima.wms.service.StockService;
import com.itheima.wms.vo.BatchVO;
import com.itheima.wms.vo.GroundingDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 业务实现类
 * 上架任务
 * </p>
 */
@Slf4j
@Service
public class GroundingServiceImpl extends CrudServiceImpl<GroundingMapper, GroundingEntity> implements GroundingService {

    @Autowired
    private ReceiptMapper receiptMapper;
    @Autowired
    private IncreaseDecreaseService increaseDecreaseService;
    @Autowired
    private ReceiptListMapper receiptListMapper;
    @Autowired
    private StockService stockService;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private LocationPlanMapper locationPlanMapper;
    @Autowired
    private StatusRecordService statusRecordService;
    @Autowired
    private StockRecordMapper stockRecordMapper;

    @Override
    @Transactional
    public BatchVO complete(List<Long> ids) {
        BatchVO.BatchVOBuilder batchVOBuilder = BatchVO.builder();
        ids.forEach(id -> {
            GroundingEntity groundingEntity = this.getById(id);
            if (null == groundingEntity) {
                log.info("id:{} 未找到", id);
                return;
            }

            // 校验清单是否有未填写的
            LambdaQueryWrapper<ReceiptListEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ReceiptListEntity::getMasterId, groundingEntity.getMasterId());
            List<ReceiptListEntity> receiptListEntities = receiptListMapper.selectList(wrapper);
            receiptListEntities = receiptListEntities.stream().filter(item -> null != item.getGroundingNum()).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(receiptListEntities)) {
                log.info("id:{} 清单未填写完成", id);
                batchVOBuilder.error(groundingEntity.getCode() + "未完成上架确认");
                return;
            }

            if (GroundingStatus.GROUNDING.getCode() != groundingEntity.getStatus()) {
                log.info("id:{} 状态不正确", id);
                batchVOBuilder.error(groundingEntity.getCode() + "状态不合法");
                return;
            }


            // 修改上架任务状态 为 上架完成
            groundingEntity.setStatus(GroundingStatus.COMPLETED.getCode());
            groundingEntity.setCompletionTime(LocalDateTime.now());
            this.updateById(groundingEntity);
            statusRecordService.saveStatus(groundingEntity);

            // 修改入库单状态 为 上架完成
            ReceiptEntity receiptEntity = receiptMapper.selectById(groundingEntity.getMasterId());
            receiptEntity.setStatus(ReceiptStatus.GROUNDING_COMPLETED.getCode());
            receiptMapper.updateById(receiptEntity);
            statusRecordService.saveStatus(receiptEntity);

            // 解冻上架库存
            unfreezeGrounding(receiptListEntities);

            // 生成损益单
            if (groundingEntity.getDifferenceNum() != 0) {
                // 差异数大于0 查询明细 生成损益单
                saveIncreaseDecrease(groundingEntity, receiptEntity);
            }
            batchVOBuilder.result(groundingEntity.getCode());
        });
        return batchVOBuilder.build();
    }

    /**
     * 生成损益单
     *
     * @param groundingEntity
     * @param receiptEntity
     */
    private void saveIncreaseDecrease(GroundingEntity groundingEntity, ReceiptEntity receiptEntity) {

        LambdaQueryWrapper<ReceiptListEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ReceiptListEntity::getMasterId, receiptEntity.getId());
        queryWrapper.ne(ReceiptListEntity::getGroundingDifferenceNum, 0);
        List<ReceiptListEntity> receiptLists = receiptListMapper.selectList(queryWrapper);
        List<IncreaseDecreaseEntity> increaseDecreaseEntityList = new ArrayList<>();
        for (ReceiptListEntity receiptList : receiptLists) {
            LambdaQueryWrapper<IncreaseDecreaseEntity> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(IncreaseDecreaseEntity::getTaskId, receiptList.getId());
            int cou = increaseDecreaseService.count(wrapper);
            if (cou > 0) {
                continue;
            }
            // 查询货品信息
            GoodsEntity goods = goodsMapper.selectById(receiptList.getGoodsId());

            // 根据库位id查询库存id
            Long locationPlanId = receiptList.getLocationPlanId();
            LambdaQueryWrapper<LocationPlanEntity> locationPlanWrapper = new LambdaQueryWrapper<>();
            locationPlanWrapper.eq(LocationPlanEntity::getGroupId, locationPlanId);
            locationPlanWrapper.orderByDesc(LocationPlanEntity::getCreateTime);
            locationPlanWrapper.last("limit 1");
            LocationPlanEntity locationPlanEntity = locationPlanMapper.selectOne(locationPlanWrapper);
            LambdaQueryWrapper<StockEntity> stockWrapper = new LambdaQueryWrapper<>();
            stockWrapper.eq(StockEntity::getLocationId, locationPlanEntity.getLocationId());
            StockEntity stockEntity = stockService.getOne(stockWrapper);

            IncreaseDecreaseEntity increaseDecreaseEntity = new IncreaseDecreaseEntity();
            increaseDecreaseEntity.setCode(CodeWorker.nextCode(CodeConstant.INCREASEDECREASE));
            increaseDecreaseEntity.setStockId(stockEntity.getId());
            increaseDecreaseEntity.setIdNum(receiptList.getGroundingDifferenceNum());// 上架差异数量
            if (null != goods.getPrice() && null != increaseDecreaseEntity.getIdNum()) {
                increaseDecreaseEntity.setIdMoney(goods.getPrice().multiply(new BigDecimal(increaseDecreaseEntity.getIdNum())));
            }
            increaseDecreaseEntity.setIdSource(IncreaseDecreaseIdSource.SJ.getCode());
            increaseDecreaseEntity.setTaskId(receiptList.getId());
            increaseDecreaseEntity.setTaskCode(groundingEntity.getCode());
            increaseDecreaseEntity.setStatus(IncreaseDecreaseStatus.CHANGE.getCode());
            increaseDecreaseEntityList.add(increaseDecreaseEntity);
        }
        if (!CollectionUtils.isEmpty(increaseDecreaseEntityList)) {
            increaseDecreaseService.saveBatch(increaseDecreaseEntityList);
        }
    }

    /**
     * 解冻上架库存
     *
     * @param receiptListEntities
     */
    private void unfreezeGrounding(List<ReceiptListEntity> receiptListEntities) {
        receiptListEntities.forEach(receiptListEntity -> {
            LambdaQueryWrapper<LocationPlanEntity> planWrapper = new LambdaQueryWrapper<>();
            planWrapper.eq(LocationPlanEntity::getGroupId, receiptListEntity.getLocationPlanId());
            List<LocationPlanEntity> dbLocationPlan = locationPlanMapper.selectList(planWrapper);
            dbLocationPlan.forEach(locationPlanEntity -> {
                StockEntity stockEntity = stockService.getOneByLocationId(locationPlanEntity.getLocationId());
                Integer original = stockEntity == null ? 0 : stockEntity.getTotal();
                Integer originalFree = stockEntity == null ? 0 : stockEntity.getFree();

                stockService.unfreeze(stockEntity.getId(), locationPlanEntity.getNum());

                StockRecordEntity stockRecordEntity = new StockRecordEntity();
                stockRecordEntity.setSourceId(receiptListEntity.getId());
                stockRecordEntity.setLocationId(locationPlanEntity.getLocationId());
                stockRecordEntity.setType(StockRecordType.RK.getCode());// 类型入库
                stockRecordEntity.setOriginal(original);
                stockRecordEntity.setOriginalFree(originalFree);
                stockRecordEntity.setWay(StockRecordWay.POSITIVE.getCode());
                stockRecordEntity.setAlteration(locationPlanEntity.getNum());
                stockRecordEntity.setResult(stockRecordEntity.getOriginal());
                stockRecordEntity.setResultFree(stockRecordEntity.getOriginalFree() + stockRecordEntity.getAlteration());
                stockRecordMapper.insert(stockRecordEntity);
            });
        });
    }

    @Override
    public IPage<GroundingDetailVO> pageDetail(Page<GroundingDetailVO> page, Map data) {
        IPage<GroundingDetailVO> iPage = this.baseMapper.selectGroundingDetail(page, data);
        return iPage;
    }
}

